#include "../include/disk.h"
#include "../include/macro_disk.h"
#include "../include/macro_constant.h"
#include "../include/macro_partition.h"
#include "../include/macro_superblock.h"
#include "../include/superblock.h"
#include "../include/ptrlist.h"
#include "../include/ptrarray.h"
#include "../include/fsext.h"
#include "../include/fsother.h"
#include "../include/state.h"
#include "../include/winapi.h"
Disk::Disk(){}
Disk::Disk(HANDLE _disk_handle,uint32 win_disk_indx_):disk_handle(_disk_handle),win_disk_index(win_disk_indx_)
{
	fs_array=getFS(scanPartitionTable());
}
Disk::~Disk(){WinAPI::closeHandle(disk_handle);}
PtrArray<FS> Disk::getFS(PtrArray<PartitionInfo>& ifs) const
{
	PtrArray<FS> ofs(ifs.size());
	for(uint32 i=0;i<ifs.size();i++)
	{
		if(ifs[i].fs_type==FS_TYPE_LINUX)
		{
			SuperBlock sublock;
			WinAPI::readData(disk_handle,ifs[i].start_sector+2,SUPER_BLOCK_SIZE,sublock.block);
			ofs.setPtr(new FsExt(ifs[i].start_sector,sublock,ifs[i].fs_type,disk_handle),i);
		}
		else 
			ofs.setPtr(new FsOther(ifs[i].start_sector,ifs[i].fs_type,disk_handle),i);
	}
	return ofs;
}
PtrArray<PartitionInfo> Disk::scanPartitionTable() const
{
	PtrList<PartitionInfo> tmp_fs(4,false);
	bool is_extend_partition=false;
	uint32 extend_partition_start_scetor=0;
	Buffer MBR(SECTOR_SIZE);
	WinAPI::readData(disk_handle,0,SECTOR_SIZE,MBR);
	for (uint32 i=0;i<ENTRY_COUNT;i++)
	{
		if (FS_TYPE(MBR.data(),i)==FS_TYPE_EXTEND1||FS_TYPE(MBR.data(),i)==FS_TYPE_EXTEND2)
		{
			Buffer EBR(SECTOR_SIZE);
			extend_partition_start_scetor = START_SCETOR(MBR.data(),i);
			is_extend_partition = true;
			uint32 sub_extend_partition_start_scetor = extend_partition_start_scetor;
			while (is_extend_partition)
			{
				is_extend_partition = false;
				WinAPI::readData(disk_handle,sub_extend_partition_start_scetor,SECTOR_SIZE,EBR);
				if (FS_TYPE(EBR.data(),0)!=FS_TYPE_EXTEND1&&FS_TYPE(EBR.data(),0)!=FS_TYPE_EXTEND2)
					tmp_fs.push(new PartitionInfo(sub_extend_partition_start_scetor + START_SCETOR(EBR.data(),0),FS_TYPE(EBR.data(),0)));
				if (FS_TYPE(EBR.data(),1)==FS_TYPE_EXTEND1||FS_TYPE(EBR.data(),1)==FS_TYPE_EXTEND2) 
				{
					sub_extend_partition_start_scetor = extend_partition_start_scetor +START_SCETOR(EBR.data(),1);
					is_extend_partition = true;
				}
			}
		}
		else
			if(FS_TYPE(MBR.data(),i)!=0)
				tmp_fs.push(new PartitionInfo(START_SCETOR(MBR.data(),i),FS_TYPE(MBR.data(),i)));
	}
	PtrArray<PartitionInfo> tmp(tmp_fs.size);
	tmp_fs.copyTo(tmp);
	return tmp;
}






